AWSTemplateFormatVersion: '2010-09-09'
Description: 'Create a static website on S3 served by CloudFront'
Parameters:
  DomainName:
    Type: String
    Description: The domain name for the site
    AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
    ConstraintDescription: must be a valid DNS zone name.
  AcmCertificateArn:
    Type: String
    Description: the Amazon Resource Name (ARN) of an AWS Certificate Manager (ACM) certificate.
    AllowedPattern: "arn:aws:acm:.*"
  S3BucketName:
    Type: String
    Description: Name for the bucket
  VaporHostedZoneID:
    Type: String
    Description: The ID of the hosted zone for the domain
    AllowedPattern: "Z[0-9A-Z]{13,}"
    ConstraintDescription: must be a valid hosted zone ID.
    Default: 'Z06581742SY16C173XCLE'
Resources:
  S3BucketForWebsiteContent:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref 'S3BucketName'
      WebsiteConfiguration:
        IndexDocument: index.html
  WebsiteCloudfront:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Comment: Cloudfront Distribution pointing to S3 bucket
        Origins:
        - DomainName: !Join [ '', !Split [ 'http://', !GetAtt 'S3BucketForWebsiteContent.WebsiteURL' ] ]
          Id: S3Origin
          CustomOriginConfig:
            OriginProtocolPolicy: 'http-only'
        Enabled: true
        HttpVersion: 'http2'
        Aliases:
        - !Ref 'DomainName'
        CustomErrorResponses:
          - ErrorCode: 403
            ResponseCode: 404
            ResponsePagePath: '/error/404/index.html'
        DefaultCacheBehavior:
          AllowedMethods:
          - GET
          - HEAD
          - OPTIONS
          Compress: true
          TargetOriginId: S3Origin
          ForwardedValues:
            QueryString: false
            Cookies:
              Forward: none
          ViewerProtocolPolicy: redirect-to-https
          ResponseHeadersPolicyId: !Ref WebsiteCloudFrontPolicies
        PriceClass: PriceClass_All
        ViewerCertificate:
          AcmCertificateArn: !Ref 'AcmCertificateArn'
          SslSupportMethod: sni-only
  WebsiteCloudFrontPolicies:
    Type: AWS::CloudFront::ResponseHeadersPolicy
    Properties:
      ResponseHeadersPolicyConfig:
        Name: Design-Security-Header-Policy
        Comment: The Vapor Design security header policy
        CorsConfig:
          AccessControlAllowCredentials: true
          AccessControlAllowHeaders:
            Items:
              - "ORIGIN"
          AccessControlAllowMethods:
            Items:
              - "GET"
              - "HEAD"
              - "OPTIONS"
          AccessControlAllowOrigins:
            Items:
              - "*"
          OriginOverride: true
        CustomHeadersConfig:
          Items:
            - Header: Permissions-Policy
              Value: accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()
              Override: false
            - Header: server
              Value: 'Vapor Design'
              Override: true
        SecurityHeadersConfig:
          ContentSecurityPolicy:
              ContentSecurityPolicy: default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self'; font-src 'self'; manifest-src 'self';
              Override: false
          ContentTypeOptions:
            Override: false
          FrameOptions:
            FrameOption: DENY
            Override: false
          ReferrerPolicy:
            ReferrerPolicy: strict-origin-when-cross-origin
            Override: false
          StrictTransportSecurity:
            AccessControlMaxAgeSec: 63072000
            IncludeSubdomains: true
            Preload: false
            Override: false
          XSSProtection:
            ModeBlock: true
            Protection: true
            Override: false
  DNSEntry:
    Type: 'AWS::Route53::RecordSetGroup'
    Properties:
      HostedZoneId: !Ref VaporHostedZoneID
      RecordSets:
        - Name: !Ref DomainName
          Type: A
          AliasTarget:
            HostedZoneId: Z2FDTNDATAQYW2
            DNSName: !GetAtt 'WebsiteCloudfront.DomainName'
        - Name: !Ref DomainName
          Type: AAAA
          AliasTarget:
            HostedZoneId: Z2FDTNDATAQYW2
            DNSName: !GetAtt 'WebsiteCloudfront.DomainName'
Outputs:
  CloudfrontURL:
    Description: 'Cloudfront URL'
    Value: !GetAtt WebsiteCloudfront.DomainName
